
// {name:'张三',age:18}  => name=张三&age=18  每个键值对 都是key=value&
function object_to_querystring(obj) {
    let str = '';
    for (let k in obj) {
        str += `${k}=${obj[k]}&`
    }
    return str.slice(0, -1)
}

console.log(object_to_querystring({ name: '张三', age: 18 }));


// throw  new Error('错误')


// 登录 
//   username password  application/x-www-form-urlencoded   
// 获取用户的详细信息  
//                   authorization
// 购物车  
//                 需要authorization  不需要content-type
//  修改密码 
//                 需要authorization  需要content-type
function creatAjax(url) {
    let base_url = url; //基准地址 localhost:8080
    function my_ajax(options = {}) {


        // 请求方式  可以不传  但是传递 必须是GET POST PUT PATCH DELETE
        if (!(options.method === undefined || /^(GET|POST)$/i.test(options.method))) {
            throw new Error('请求方式仅仅支持GET和POST,敬请期待更新');
        }
        // 请求地址  必须传  
        if (!options.url) {
            throw new Error('请求地址必须传递');
        }
        // 是否是异步 可以不传  但是传递必须是 布尔类型 
        if (!(options.aysnc === undefined || typeof options.aysnc === 'boolean')) {
            throw new Error('aysnc只能是布尔类型 ');
        }
        // 携带参数  可以不传递 但是传递必须是字符串 或者对象 
        if (!(options.data === undefined || typeof options.data === 'string' || options.data.constructor === Object)) {
            throw new Error('data参数只能是string 或者 object 类型 ');

        }
        // 请求头  可以不传 但是传递必须是 对象 
        //              {'content-type':'application/x-www-form-urlencoded'}
        if (!(options.headers === undefined || options.headers.constructor === Object)) {
            throw new Error('请求头必须是一个对象结构');

        }

        // 数据解析 
        //      可以不传   传的话 必须 是 'string'或者'json '

        if (!(options.dataType === undefined || /^(string|json)$/i.test(options.dataType))) {
            throw new Error('datatype必须是string或者json');
        }


        // 需要设定默认值 

        const _default = {
            url: base_url+options.url,
            method: options.method || 'GET',
            async: options.async || true,
            data: options.data || '',
            headers: { 'content-type': 'application/x-www-form-urlencoded', ...options.headers },
            dataType: options.dataType || 'string'
        }

        // 如果参数_default.data是对象 需要将对象转成 查询字符串  
        // 如果是字符串直接拼接 
        if (_default.data.constructor === Object) {
            _default.data = object_to_querystring(_default.data)
        }
        // www.baidu.com?username=zhangsan&age=18
        if (/^GET$/i.test(_default.method)) {
            _default.url += '?' + _default.data
        }

        const p = new Promise(function (resolve, reject) {
            const xhr = new XMLHttpRequest();

            xhr.open(_default.method, _default.url, _default.aysnc);


            // 配置响应事件 

            xhr.onload = function () {
                // 需要和不需要解析json  
                if (_default.dataType === 'string') {
                    // 不需要解析
                    resolve({ code: 1, message: '成功', info: xhr.responseText })
                    return
                }

                // 如果返回的是json 

                // JSON.parse()

                // 成功拿到消息  
                // 成功以后执行函数

                // 失败返回错误消息 
                // 执行一个函数

                try {
                    const res = JSON.parse(xhr.responseText);
                    resolve({ code: 1, message: '成功', info: res });
                }
                catch (e) {
                    resolve({ code: 0, message: '失败', info: e })
                }


            }

            // get post 请求 不太一样 
            // post请求需要设置请求头

            if (/^POST$/i.test(_default.method)) {
                xhr.setRequestHeader('content-type', _default.headers['content-type'])
            }

            if (_default.headers.authorization) {
                xhr.setRequestHeader('authorization', _default.headers.authorization)
            }

            // get请求send 里边什么也不写 
            // post 请求  
            /^POST$/i.test(_default.method) ? xhr.send(_default.data) : xhr.send();
        })


        return p;  // 返回promise对象  

    }

    return  my_ajax
}

// export default my_ajax


const res = creatAjax('http://localhost:8080');
//返回值是my_ajax函数
// console.log(res);

// res({url:'/test/first'}).then(r=>console.log(r));
// res({url:'/test/second'}).then(r=>console.log(r));
// res({url:'/test/third',data:{name:'zhangsan',age:66}}).then(r=>console.log(r));
// res({url:'/test/fourth',method:'POST',data:{name:'zhangsan',age:66}}).then(r=>console.log(r));


async function fn1(){
    const r1 = await res({url:'/test/first'});
    console.log(r1);

    const r2 = await res({url:'/test/second'});
    console.log(r2);

    const r3 = await res({url:'/test/third',data:{name:'zhangsan',age:66}});
    console.log(r3);

    const r4 = await res({url:'/test/fourth',method:'POST',data:{name:'zhangsan',age:66}});
    console.log(r4);

    const r5 = await res({url:'/goods/list',data:{current:1,pagesize:10}});
    console.log(r5);
}

fn1()